#pragma once
#include<iostream>
#include<list>
using namespace std;

namespace wzy
{
	template<class T>
	struct list_ndoe
	{
		T _data;
		list_node<T>* _next;
		list_node<T>* _prev;
		list_node(const T& x = T())
			:_data(x)
			, _next(nullptr)
			, _prev(nullptr)

	};

	// T T& T*
	// T cosnt T& const T*
	template<class T,class Ref,class Ptr>
	struct _list_iterator
	{
		typedef _list_iterator<T,Ref,Ptr> self;
		typedef list_node<T> Node;
		Node* _node;

		_list_iterator(Node* node)
			:_node(node)
		{}

		Ref operator*()
		{
			return _node->_data;
		}

		self& operator++()
		{
			_node = _node->next;
			return *this;
		}

		slef& operator--()
		{
			_node = _node->prev;
			return *this;
		}

		slef& operator++(int)
		{
			slef temp(*this);
			_node = _node->next;
			return temp;
		}

		slef& operator--(int)
		{
			slef temp(*this);
			_node = _node->prev;
			return temp;
		}

		Ptr operator->()
		{
			return &(_node->_data);
		}

		bool operator!=(const self& s)
		{
			return _ndoe != s._node;
		}

	};

	template<class Iterator,class Ref, class Ptr>
	class reverse_iterator
	{
		typedef rever_iterator<T, Ref, Ptr> self;

	public:
		reverse_iterator(iterator it)
			:_it(it)
		{}

		Ref operator*()
		{
			Iterator temp = _it;
			return *(--temp);
		}

		self& operator++()
		{
			--_it;
			return *this;
		}

		slef& operator--()
		{
			_it++;
			return *this;
		}

		Ptr& operator->()
		{
			return &(operator*());
		}

		bool operator!=(const Self& s)
		{
			return _it != s._it;
		}

		bool operator==(const Self& s)
		{
			return _it == s._it;
		}

	private:
		iterator _it;
	};
}
